using System;
using System.Diagnostics;

using System.Collections.Generic;
using System.Collections;
using CStock;
using CUtil;

namespace CStock
{
	/// <summary>
	/// Summary description for TradeStep.
	/// </summary>
	public class TradeStep : ITradeStep
	{
		
		protected bool intraday;
        //protected bool initialized;

		protected int tradeSystemIndex;
		protected DateTime currentDate;
		protected string indicatorsString ;

		protected int dateIndex;
		protected double prognosis;


		//current values
		protected bool buySellOccurs; // is an Integer
		protected double transactionCosts;
		
        protected double money ;
		protected int numberOfShares ;
		protected double bankingCosts ;
        protected double bankingCostsPercentage;
        
		protected int numberOfSharesTraded;

		protected double totalBankingCosts ;
		
		double indicatorValue;

		protected int dateMinIndex;
		protected int dateMaxIndex;

		protected DateTime dateMin;
		protected DateTime dateMax;
		protected bool indicatorsEvaluated;

		System.Collections.ArrayList prognosisAll;
		
		protected System.Collections.ArrayList tradeEvents;
		protected double moneyStart;
        protected double moneyStartPortfolio;


		protected double quoteShareLastTrade ;
		protected TradeType tradeType;

		IIndicators indicatorsSell;

		IIndicators indicatorsBuy;

		protected TradeWriteModes tradeWriteMode;
	
		protected double maxMoneyForBuyPerShare = 10000;
		protected double maxMoneyForBuyPerPortfolio;


		protected IPortfolio portfolio;
	
		protected double quoteShareMaxSinceLastTrade;
		protected double quoteShareMinSinceLastTrade;



		protected double moneyAtYearStartPerShare;
		protected double moneyAtYearStartPerPortfolio;

		protected double quoteShareAtYearStart;

		

		protected NameObjectCollection performancePerYearCollection;
		protected NameObjectCollection performanceBuyAndHoldPerYearCollection;
		protected NameObjectCollection performanceRelativePerYearCollection;


		public  CUtil.TradeType tradeTypePossible;

		protected string lastYear;

		protected double futuresMoneyPerTick = 25;
		protected double futuresContractValue = 2000;
		protected double futuresBankCost = 2;

		protected bool futuresTrade;

		protected double minimalTransactionCost;
		 protected double constSingleTransactionPercentageCost ;
		protected double minmalTransactionAmount;
		protected double maximalTransactionCost;

		protected double tradeStopLossDynamicLimit;


		protected CUtil.TradeMoneyType tradeTypeMoney;

        protected bool tradeSimulationInitiaded;
        protected ITradeSystem tradeSystem;
        protected ITradeSystem tradeSystemForShortSell;
	
        private IDataItem dataItem_SelectedForPortfolio;
        private IDataItem dataItem;



        private ITrader trader;

        protected double lastBuyTransaction;
        protected double winLoss;
      
       
        public TradeStep(IDataItem MyparentDataItem)
        {
            this.dataItem = MyparentDataItem;

        }
     
        public TradeStep(IPortfolio MyPortf)
        {
            
            this.portfolio = MyPortf;
        }
        
		//protected double maxMoneyForBuyPerShare;
        public bool Init(bool resetIndicators, CUtil.TradeMoneyType tradeType, double shareQuoteInitial)
		{

            Reset(resetIndicators, tradeType, shareQuoteInitial);
            return true;
			
		}
      
        protected bool GetOHLCTimeLimits(out DateTime dateMin, out DateTime dateMax, IListQuotes ohlc)
        {

            //no adjustment
            if (ohlc != null && ohlc.Count > 0)
            {
                dateMax = ohlc[ohlc.Count - 1].DATE;
                dateMin = ohlc[0].DATE;
                return true;
            }

            dateMax = new DateTime(1, 0, 0);
            dateMin = new DateTime(1, 0, 0);

            return false;

        }
        public bool ResetDatesFromQuotes(bool resetIndicators, IDataProvider dc, CUtil.TradeMoneyType tradeType)
        {

            //tradeStep = new TradeStep();
            this.dataItem.DataClass = dc as IDataClass;
            double shareInitialQuote = dc.QuoteCollection[0].CLOSEc;
            this.Init(resetIndicators, tradeType, shareInitialQuote);

            DateTime dMin;
            DateTime dMax;
            if (!GetOHLCTimeLimits(out dMin, out dMax, dc.QuoteCollection))
                return false;//during program start

            this.DateMin = dMin;
            this.DateMax = dMax;
            this.DateMinIndex = 0;
            this.DateMaxIndex = dc.QuoteCollection.Count - 1;

            this.Date = this.DateMin;
            this.DateIndex = this.DateMinIndex;//start from 0 // or a day less than first day - e.g. -1 ??
            this.TradeEvents = new System.Collections.ArrayList();
            this.winLoss = 0f;
            return true;

        }
        public void Reset( bool resetIndicators, CUtil.TradeMoneyType tradeType, double shareStartValue)
		{
			this.tradeTypeMoney = tradeType;
			this.minmalTransactionAmount = 1000; // do not buy/sell if the amount is less than this
			this.maximalTransactionCost = -69.95F;
			this.minimalTransactionCost = -4.95F;
			this.constSingleTransactionPercentageCost = 0.25F;
			this.money = 0F;
			this.moneyStart = this.money;
            this.moneyStartPortfolio = this.money;
			maxMoneyForBuyPerShare = 10000F;

			tradeTypePossible = CUtil.TradeType.Nothing;
			this.performancePerYearCollection = new NameObjectCollection();
			this.performanceRelativePerYearCollection = new NameObjectCollection();
			this.performanceBuyAndHoldPerYearCollection = new NameObjectCollection();

			this.quoteShareAtYearStart = -1000000;
			this.moneyAtYearStartPerShare = this.maxMoneyForBuyPerShare;

			this.numberOfShares = 0;

            this.winLoss = 0f;


			this.tradeType = CUtil.TradeType.Nothing;
		
			this.totalBankingCosts = 0;
            bankingCostsPercentage = 0.3F;
			this.transactionCosts = 0;
			this.tradeEvents = new System.Collections.ArrayList();
            if (resetIndicators)
            {
                this.indicatorsBuy = null;
                this.indicatorsSell = null;
            }
			this.dateIndex = 0;
			if(this.portfolio != null)
			{
				this.maxMoneyForBuyPerPortfolio = (double)0.5 * this.maxMoneyForBuyPerShare * this.portfolio.DataItems.Count;
				this.moneyAtYearStartPerPortfolio = this.maxMoneyForBuyPerPortfolio;
			}

			this.tradeStopLossDynamicLimit = -10000F;

            
            if (tradeType == CUtil.TradeMoneyType.TradeOneShare)
            {
                this.money = shareStartValue;
                this.moneyStart = shareStartValue;
                moneyAtYearStartPerShare = shareStartValue;
                this.moneyStartPortfolio = shareStartValue;
                this.maxMoneyForBuyPerShare = shareStartValue;
                this.maxMoneyForBuyPerPortfolio = shareStartValue;

            }
            else
            {
                this.Money = this.MaxMoneyForBuyPerShare;
                this.MoneyStart = this.MaxMoneyForBuyPerShare;
            }





		}
		public  int DataClassIndex
		{
			get
			{
				for(int i = 0; i < this.portfolio.DataItems.Count; i++)
				{
					if( this.portfolio.DataItems[i].DataClass == this.dataItem.DataClass)
					{
						return i;
					}
								
				}
				return -1;
			}
		}
        
        public IDataItem DataItem_SelectedForPortfolio
        {
            get
            {
               return this.dataItem_SelectedForPortfolio;
            }
            set
            {
               this.dataItem_SelectedForPortfolio = value;
            }
        }

        public int DataItemSelected_Index_ForPortfolio
        {
            get
            {
                for (int i = 0; i < this.portfolio.DataItems.Count; i++)
                {
                    if (this.portfolio.DataItems[i].DataClass == this.dataItem.DataClass)
                    {
                        return i;
                    }

                }
                return -1;
            }
        }
        public int TradeSystemIndex
        {
            get
            {
                return this.tradeSystemIndex;
            }
            set
            {
                this.tradeSystemIndex = value;
            }
        }
		public  double ValueShares
		{
			get
			{
				double val = 0;
				if(this.futuresTrade)
				{
					val = this.numberOfShares * this.futuresContractValue;
				}
				else
				{
					val = this.numberOfShares * this.QuoteShare;
				}
				return val;
			}
		
		}
		public  double ValueTotal
		{
			get
			{
                double fval = 0f;
                if(this.dataItem != null)
				{
					fval = this.ValueShares + this.Money;
					fval = (double)System.Math.Round(fval, 2);
					return Convert.ToDouble(fval);

				
				}
				else
				{

					try
					{
						System.Diagnostics.Debug.Assert(this.portfolio != null,"DataClass AND portfolio are not set in TradeStep");

						fval = 0F;
						if(this.portfolio != null)
						{
						
							for(int i = 0; i < this.portfolio.DataItems.Count; i++)
							{
                                TradeStep ts = this.portfolio.DataItems[i].TradeStep as TradeStep;
								
								//TradeStep ts = this.portfolio.DataItems[i].DataClass.TradeSimulation.TradeStep as TradeStep;
								fval += ts.ValueTotal;
							}
						
						}
						fval += this.money;
						fval = (double)System.Math.Round(fval, 2);
						return Convert.ToDouble(fval);
					}
					catch(Exception exc)
					{
						Debug.Assert(false,"Error calculating portfolio value ",exc.Message);
						return 0;
					}
					
				}
			}
	
		}
		public double QuoteShareInitial
		{
			get
			{
                IListQuotes qColl = null;
                if (this.dateIndex < this.dateMinIndex)
                {
                    qColl = this.dataItem.DataClass.QuoteCollection;
                    return qColl[0].CLOSEc;
                    //return 0F;
                }
					
				qColl = this.dataItem.DataClass.QuoteCollection;
				return qColl[this.dateMinIndex].CLOSEc;
			}
		}

        public double PerformanceBuyAndHold_Share_PerYear
        {
            get
            {
                if (this.intraday)
                {
                    return 0F;
                }
                else
                {
                    //TimeSpan diff = this.dateMax - this.dateMin;
                    TimeSpan diff = this.Date - this.dateMin;
                    int days = diff.Days;

                    //Debug.Assert(days != 0, "Software error : Date Difference is zero - please check reset trading function");
                    if (days == 0)
                        return 0F;


                    double perfPerYear = (this.PerformanceBuyAndHold_Share * 365) / days;
                    perfPerYear = (double)System.Math.Round(perfPerYear, 2);
                    return perfPerYear;
                }
            }
        }
		public  double PerformanceBuyAndHold_Share
		{
			get
			{
				if(this.dataItem != null)
				{
					double f = QuoteShareInitial;
					double fSharePerfIn100Percent ;
					if(f == 0)
					{
						fSharePerfIn100Percent = 100;
					}
					else
					{
						fSharePerfIn100Percent = this.QuoteShare * 100 / f ;
					}
					
                    fSharePerfIn100Percent = fSharePerfIn100Percent - 100;
                    fSharePerfIn100Percent = (double)System.Math.Round(fSharePerfIn100Percent, 2);
                    return fSharePerfIn100Percent;
				}
				else
				{
					double fValInitial = 0F;
					double fValEnd = 0F;

					
					for(int i = 0; i < this.portfolio.DataItems.Count; i++)
					{
						TradeStep ts = this.portfolio.DataItems[i].TradeStep as TradeStep;
						double fInitial = ts.QuoteShareInitial;
                        if (fInitial > 0)
                        {
                            int noShares = Convert.ToInt32(this.maxMoneyForBuyPerShare / fInitial);
                            fValInitial += fInitial * noShares;
                            fValEnd += ts.QuoteShare * noShares;
                        }
                        else
                        {
                            System.Windows.Forms.MessageBox.Show("SW Error : Initial quote values for shares are incorrect (0) ");
                            return -9999;
                        }
					}

                  
					
					double fSharePerfIn100Percent = fValEnd * 100 / fValInitial ;
					fSharePerfIn100Percent = fSharePerfIn100Percent -100;
					fSharePerfIn100Percent = (double)System.Math.Round(fSharePerfIn100Percent , 2);
					return fSharePerfIn100Percent;

				}
			}
		}
		public  string DateDisplay
		{
			get
			{
				DateTime dt = this.currentDate;
				if(this.intraday)
				{
					return dt.ToShortTimeString(); 
				}
				else
				{
					return dt.ToShortDateString(); 
				}
			}
		}

		public  DateTime Date
		{
			get
			{
				return this.currentDate;
			}
			set
			{
				this.currentDate = value;
				if(value != this.dateMin)
				{
					//set performance of last year !
					
					if(this.dateMin.Year < this.currentDate.Year)
					{
						if(value.Month == 1 )
						{
							lastYear = (this.Date.Year -1).ToString();
							if(value.Day == 1)
							{
								double f = this.PerformanceRelativeOfLastYear;//calls also the normal perf.
								//Debug.WriteLine("Performance: " + f.ToString() + " --share - " + PerformanceRelativeOfLastYear);
								//f = PerformanceRelativeOfLastYear;

							}
							if(value.Day < 5)
							{
								//perhaps the other days were holidays and we do not have share quotes
								if(! this.performancePerYearCollection.Contains(lastYear))
								{
									//calls also the normal perf.
									double f = this.PerformanceRelativeOfLastYear;
									//Debug.WriteLine("Performance: " + f.ToString() + " --share - " + PerformanceRelativeOfLastYear);
						
								}
							}

						}
					}
				}
				
			}
		}
		public double TradeStopLossDynamicLimit
		{
			get
			{
				return this.tradeStopLossDynamicLimit;
			}
			set
			{
				this.tradeStopLossDynamicLimit = value;
			}
		}
		public  string IndicatorsString
		{
			get
			{
				return this.indicatorsString;
			}
			set
			{
                this.indicatorsString = value;
			}
		}


        public double WinLoss
        {
            get
            {
                if (this.tradeTypeMoney == TradeMoneyType.TradeOneShare)
                {
                    return this.winLoss;
                }
                else
                {
                    double fValTotal = this.ValueTotal;
                    double f;
                    if (this.dataItem != null)
                    {
                        f = fValTotal - this.moneyStart;
                    }
                    else
                    {
                        f = fValTotal - this.moneyStartPortfolio;
                        
                    }
                    return f;
                }
            }
            set
            {
                this.winLoss = FormatNumbers.FormatDoubleWithTwoDigits(value); 
            }
            
        }

        public double CalcPortfolioPerformance_TradeOneShare()
        {
            if (this.portfolio != null)
            {
                //make an average value of the performance of all shares
                double fTotal = 0f;
                
                for (int i = 0; i < this.portfolio.DataItems.Count; i++)
                {
                    
                    IDataItem di = this.portfolio.DataItems[i];
                    fTotal += di.TradeStep.Performance;
                    //double fLastWinLoss = di.DataClass.QuoteCollection[this.Date].CLOSEc + di.TradeStep.LastBuyTransaction;
                    //allLastWinLosses += fLastWinLoss;
                    //allWinLosses += di.TradeStep.WinLoss;

                    
                }
                fTotal = fTotal / this.portfolio.DataItems.Count;
                fTotal = (double)System.Math.Round(fTotal, 2);
                return fTotal;
                

            }
            return 0f;


        }
        private double CalcPerformanceTradeOneShare()
        {
            try
            {
                double fPerformanceIn100Percent;
                if (this.dataItem != null)
                {
                    fPerformanceIn100Percent = this.moneyStart;
                    //fPerformanceIn100Percent = fValTotal * 100 / this.moneyStart;
                    //calculate additional winLoss due to current share price
                    double fLastWinLoss = this.dataItem.DataClass.QuoteCollection[this.Date].CLOSEc + this.lastBuyTransaction;

                    double fVal = (this.winLoss + fLastWinLoss) * 100 / fPerformanceIn100Percent;
                    fVal = (double)System.Math.Round(fVal, 2);
                    return fVal;

                }
                else
                {

                    return CalcPortfolioPerformance_TradeOneShare(); ;

                }
               
            }
            catch (Exception ex)
            {
                string id = string.Empty;
                if(this.dataItem != null)
                    id = this.dataItem.ID;
                else
                    id = this.portfolio.ID;

                Debug.Assert(false, "Error calculating Performance for : " + id + "; " + ex.Message);
                return 0f;
            }
        }
		public  double Performance
		{
			get
			{
				
                if (this.tradeTypeMoney == TradeMoneyType.TradeOneShare)
                {
                    return CalcPerformanceTradeOneShare();

                }
                else
                {
                    return CalcPerformance();
                }
				
			}
		}
        private double CalcPerformance()
        {
            try
            {
                double fValTotal = this.ValueTotal;
                double fPerformanceIn100Percent;
                if (fValTotal < 0.1)
                {
                    return 0F;
                }
                if (this.dataItem != null)
                {
                    fPerformanceIn100Percent = fValTotal * 100 / this.maxMoneyForBuyPerShare;
                }
                else
                {
                    fPerformanceIn100Percent = fValTotal * 100 / this.maxMoneyForBuyPerPortfolio;
                }

                double fV1 = fPerformanceIn100Percent - 100;
                fV1 = (double)System.Math.Round(fV1, 2);
                return fV1;
            }
            catch (Exception ex)
            {
                string id = string.Empty;
                if (this.dataItem != null)
                    id = this.dataItem.ID;
                else
                    id = this.portfolio.ID;

                Debug.Assert(false, "Error calculating Performance for : " + id + "; " + ex.Message);
                return 0f;
            }

        }
        private double CalculatePerfLastYear(double fTotal)
        {
            double fPerformanceIn100Percent = 0f;
            double fVal = fTotal - this.moneyAtYearStartPerShare;
            switch (tradeTypeMoney)
            {
                case CUtil.TradeMoneyType.TradeOneShare:
                    {
                        fPerformanceIn100Percent = fVal * 100 / this.moneyAtYearStartPerShare;
                        break;
                    }
                case CUtil.TradeMoneyType.TradeWithAllMoney:
                    {
                        
                        fPerformanceIn100Percent = fVal * 100 / this.moneyAtYearStartPerShare;
                        break;
                    }
                case CUtil.TradeMoneyType.TradeWith10000:
                    {
                        fPerformanceIn100Percent = fVal * 100 / this.moneyAtYearStartPerShare;
                        break;
                    }
                default:
                    {
                        fPerformanceIn100Percent = fVal * 100 / this.maxMoneyForBuyPerShare;
                        break;
                    }
            }
            return fPerformanceIn100Percent;
        }
        
		protected  double PerformanceOfLastYear
		{
			get
			{
				double fPerformanceIn100Percent;
                double fTotal = this.ValueTotal;
                double fVal ;
				if(this.dataItem != null)
				{


                    fPerformanceIn100Percent = CalculatePerfLastYear(fTotal);
					this.moneyAtYearStartPerShare = fTotal;
				}
				else
				{
					
					fVal = fTotal - this.moneyAtYearStartPerPortfolio;
					
					fPerformanceIn100Percent = fVal * 100/this.maxMoneyForBuyPerPortfolio;
					this.moneyAtYearStartPerPortfolio = fTotal;
				}
				
				fVal = (double)System.Math.Round(fPerformanceIn100Percent , 2);
				this.performancePerYearCollection.Add(this.Date.Year - 1, fVal);
				

				return fVal;
			}
		}

		protected  double PerformanceRelativeOfLastYear
		{
			get
			{
				if(this.dataItem != null)
				{
					if(this.quoteShareAtYearStart <= 0)
						this.quoteShareAtYearStart = this.QuoteShareInitial;

					double fSharePerfIn100Percent ;

				
						
					if(this.quoteShareAtYearStart == 0)
					{
						fSharePerfIn100Percent = 100;
						this.quoteShareAtYearStart = this.QuoteShare;
					}
					else
					{
						fSharePerfIn100Percent = this.QuoteShare * 100 / this.quoteShareAtYearStart ;
						this.quoteShareAtYearStart = this.QuoteShare;
					}
					//---------------------------------
					//share performance
				
					double perf = fSharePerfIn100Percent - 100;
					perf = (double)System.Math.Round(perf , 2);
					this.performanceBuyAndHoldPerYearCollection.Add(this.Date.Year - 1,perf);

					
					perf = this.PerformanceOfLastYear - perf;
					perf = (double)System.Math.Round(perf , 2);

					this.performanceRelativePerYearCollection.Add(this.Date.Year -1 ,perf);
					return perf;
				}
				else
				{
					//portfolio!
					double fValInitial = 0F;
					double fValEnd = 0F;

					
					for(int i = 0; i < this.portfolio.DataItems.Count; i++)
					{
                        TradeStep ts = this.portfolio.DataItems[i].TradeStep as TradeStep;
						
						if(ts.QuoteShareInitial != 0)
						{
							int noShares = Convert.ToInt32(this.maxMoneyForBuyPerShare / ts.QuoteShareInitial);
							fValInitial += ts.QuoteShareInitial * noShares;
							fValEnd += ts.QuoteShare * noShares;
						}
					}
						
					
					double fSharePerfIn100Percent = fValEnd * 100 / fValInitial ;
					double perf = fSharePerfIn100Percent - 100;
					perf = (double)System.Math.Round(perf , 2);
					this.performanceBuyAndHoldPerYearCollection.Add(this.Date.Year - 1,perf);


					perf = this.PerformanceOfLastYear - perf;
					perf = (double)System.Math.Round(perf , 2);
					this.performanceRelativePerYearCollection.Add(this.Date.Year -1,perf);
					return perf;

				}
			}
		}

		[System.Xml.Serialization.XmlIgnoreAttribute()]
		public double PerformancePerYear
		{
			get 
			{ 
				if(this.intraday)
				{
					return 0F;
				}
				else
				{
					//TimeSpan diff = this.dateMax - this.dateMin;
                    TimeSpan diff = this.Date - this.dateMin;
                    int days = diff.Days;

                    //Debug.Assert(days != 0, "Software error : Date Difference is zero - please check reset trading function");
                    if (days == 0)
                        return 0F;

					
					double perfPerYear = (this.Performance * 365)/days;
					perfPerYear = (double)System.Math.Round(perfPerYear , 2);
					return perfPerYear;
				}
			}
		}
		[System.Xml.Serialization.XmlIgnoreAttribute()]
		public double PerformanceIntraday
		{
			get 
			{ 
				if(this.intraday)
				{
					return this.Performance;
				}
				else
				{
					return 0F;
					
				}
			}
		}

		[System.Xml.Serialization.XmlIgnoreAttribute()]
		public double PerformanceOfLastTrade
		{
			get 
			{ 
				double valueTotal = this.ValueTotal;
				double percent = 0F;
				TradeEvent eventPrevious = null ;
				TradeEvent eventCurrent = null ;
				
				if(this.TradeEvents.Count > 1)
				{
					eventPrevious = this.TradeEvents[this.TradeEvents.Count -2] as TradeEvent;
					eventCurrent = this.TradeEvents[this.TradeEvents.Count -1] as TradeEvent;
                

				}
				if(eventPrevious == null)
				{
					return 0F;
				}
				

				TimeSpan ts = this.Date - eventPrevious.Date;
				double money = valueTotal - eventPrevious.Quote;

				switch(this.tradeType)
				{
					case CUtil.TradeType.SellShort10000:
					{
						money = -money;
						break;
					}
					case CUtil.TradeType.SellShort10000Again:
					{
						money = -money;
						break;
					}
					case CUtil.TradeType.BuyShort :
					{
						//money = System.Math.Abs(money);
						break;
					}
				}
				

				if(ts.Days > 0)
				{
					//money per year:
					double moneyPerYear = money * 365/ ts.Days;
					//how much percent is this from my portfolio
					percent = moneyPerYear * 100 / this.maxMoneyForBuyPerShare;

					eventCurrent.TradeSuccessInPercent = percent;
                    SetTradeEventType(percent, eventCurrent);

				}
				return percent;
			}
		}

        private void SetTradeEventType(double percent, TradeEvent eventCurrent)
        {
            if (percent > 5)
            {
                //I am a win trade only if I get more than 5 % for my money per year
                eventCurrent.TradeEventType = CUtil.TradeEventType.Win;
            }
            else if (percent > 0)
            {
                eventCurrent.TradeEventType = CUtil.TradeEventType.Neutral;

            }
            else
            {
                switch (this.tradeType)
                {
                    case CUtil.TradeType.Buy:
                        {
                            eventCurrent.TradeEventType = CUtil.TradeEventType.Investing;
                            break;
                        }

                    case CUtil.TradeType.Buy10000:
                        {
                            break;
                        }
                    case CUtil.TradeType.Buy10000Again:
                        {
                            break;
                        }
                    case CUtil.TradeType.BuyStopLoss:
                        {
                            break;
                        }
                    case CUtil.TradeType.BuyStopWin:
                        {
                            break;
                        }
                    case CUtil.TradeType.SellShort10000:
                        {
                            break;
                        }
                    case CUtil.TradeType.SellShort10000Again:
                        {
                            break;
                        }
                    default:
                        {
                            eventCurrent.TradeEventType = CUtil.TradeEventType.Loose;
                            break;
                        }

                }



            }
        }
		

		
		[System.Xml.Serialization.XmlIgnoreAttribute()]
		public NameObjectCollection PerformancePerYearCollection
		{
			get 
			{ 
				//				//get the year intervalse
				//				TimeSpan diff = this.dateMax - this.dateMin;
				//				int days = diff.Days;
				//				double perfPerYear = (this.Performance * 365)/days;
				//				perfPerYear = (double)System.Math.Round(perfPerYear , 2);
				return performancePerYearCollection;
			}
		}
		public NameObjectCollection PerformanceRelativePerYearCollection
		{
			get 
			{ 
				return performanceRelativePerYearCollection;
			}
		}
		public NameObjectCollection PerformanceBuyAndHoldPerYearCollection
		{
			get 
			{ 
				return performanceBuyAndHoldPerYearCollection;
			}
		}

		
		public  double PerformanceRelative
		{
			get
			{
			
				double fVal = 0F;
				double fPerfShare = this.PerformanceBuyAndHold_Share;
				double fPerf = this.Performance ;
				fVal = fPerf -  fPerfShare ;
				fVal = (double)System.Math.Round(fVal , 2);

				return fVal;
			}
		
		}
		[System.Xml.Serialization.XmlIgnoreAttribute()]
		public double PerformanceRelativePerYear
		{
			get 
			{ 
				if(this.intraday)
				{
					return 0F;
				}
				else
				{
					TimeSpan diff = this.dateMax - this.dateMin;
					int days = diff.Days;
					double perfPerYear = (this.PerformanceRelative * 365)/days;
					perfPerYear = (double)System.Math.Round(perfPerYear , 2);
					return perfPerYear;
				}
			}
		}
		public  double PerformanceRelativeFactor
		{
			get
			{
			
				double fVal = 0F;
				double fPerfShare = this.PerformanceBuyAndHold_Share;
				double fPerf = this.Performance ;
				if(fPerfShare == 0F)
				{
					fVal = 	fPerf /1;

				}
				else
				{
					if(fPerfShare < 0 )
					{
						if(fPerf > 0)
						{
							fVal = 	fPerf - fPerfShare;
						}
						else
						{
							fVal = 	fPerf /fPerfShare ;
						}
					}
					else if(fPerf < 0)
					{
						fVal = 	 - fPerfShare ;
					}
					else
					{
						fVal = 	fPerf /fPerfShare ;
					}
					
					
				}
				
				
				fVal = (double)System.Math.Round(fVal, 2);
				return fVal;
			}
		
		}
		public  int DateIndex
		{
			get
			{
                if (this.dateIndex < 0)
                {
                    this.dateIndex = this.dataItem.DataClass.QuoteCollection.IndexOf(this.Date);
                }
				return this.dateIndex;
			}
			set
			{
				this.dateIndex = value;
			}
		}
		public  int DateMinIndex
		{
			get
			{
		
				return this.dateMinIndex;
			}
			set
			{
				this.dateMinIndex = value;
			}
		}
		public  int DateMaxIndex
		{
			get
			{
				return this.dateMaxIndex;
			}
			set
			{
				this.dateMaxIndex = value;
			}
		}

		public  double Prognosis
		{
			get
			{
				return this.prognosis;
			}
			set
			{
				this.prognosis = value;
			}
		}
		public  System.Collections.ArrayList PrognosisAll
		{
			get
			{
				return this.prognosisAll;
			}
			set
			{
				this.prognosisAll = value;
			}
		}
		public  System.Collections.ArrayList TradeEvents
		{
			get
			{
				return this.tradeEvents;
			}
			set
			{
				this.tradeEvents = value;
			}
		}
	
		public  bool BuySellOccurs
		{
			get
			{
				return this.buySellOccurs;
			}
			set
			{
				this.buySellOccurs = value;
			}
		}
		public  bool Intraday
		{
			get
			{
				return this.intraday;
			}
			set
			{
				this.intraday = value;
			}
		}
		
		public  double TransactionCosts
		{
			get
			{
				return this.transactionCosts;
			}
			set
			{
				this.transactionCosts = value;
			}
		}

        public double LastBuyTransaction
		{
			get
			{


                return this.lastBuyTransaction;

			}
			set
			{
                this.lastBuyTransaction = value;
			}
		}
        public  double Money
		{
			get
			{
				
                this.money = Convert.ToDouble( System.Math.Round(this.money, 2));
                return this.money;

			}
			set
			{
				this.money = value;
			}
		}

		
		public  int NumberOfShares
		{
			get
			{
				if(this.dataItem != null)
				{
					return this.numberOfShares;
				}
				else
				{
					int iNum = 0;
					for(int i = 0; i < this.portfolio.DataItems.Count; i++)
					{
                        TradeStep ts = this.portfolio.DataItems[i].TradeStep as TradeStep;
						iNum += ts.NumberOfShares ;
					}
				
					return iNum;

				}
			}
			set
			{
				this.numberOfShares = value;
			}
		}
		public  double BankingCosts
		{
			get
			{
				return this.bankingCosts;
			}
			set
			{
				this.bankingCosts = value;
			}
		}
        public double BankingCostsPercentage
		{
			get
			{
                return this.bankingCostsPercentage;
			}
			set
			{
                this.bankingCostsPercentage = value;
			}
		}
        
		public  int NumberOfSharesTraded 
		{
			get
			{
				return this.numberOfSharesTraded;
			}
			set
			{
				this.numberOfSharesTraded = value;
			}
		}


		
		public  double IndicatorValue
		{
			get
			{
				return this.indicatorValue;
			}
			set
			{
				this.indicatorValue = value;
			}
		}

		public  double TotalBankingCosts
		{
			get
			{
				return this.totalBankingCosts;
			}
			set
			{
				this.totalBankingCosts = value;
			}
		}
		public  bool IndicatorsEvaluated
		{
			get
			{
				return this.indicatorsEvaluated;
			}
			set
			{
				this.indicatorsEvaluated = value;
			}
		}
		public  DateTime DateMin
		{
			get
			{
				return this.dateMin;
			}
			set
			{
				this.dateMin = value;
			}
		}
		public  DateTime DateMax
		{
			get
			{
				return this.dateMax;
			}
			set
			{
				this.dateMax = value;
			}
		}
		public  bool ShareDataAvailableForCurrentDate(DateTime portfolioDate)
		{
            try
            {
                if (this.DateIndex < 0)
                    return false;
                //try to get a trade index simple (should work for 4 days of the week
                //this.TradeStep.DateIndex gets increased automatically by StepShare !!

                IListQuotes qColl = this.dataItem.DataClass.QuoteCollection;
                DateTime dtTry = qColl[this.dateIndex].DATE;
                if (dtTry == portfolioDate)
                {
                    return true;
                }
                return false;
            }
            catch (Exception ex)
            {
                Debug.Assert(false, "Error in ShareDataAvailableForCurrentDate: " + ex.Message);
                return false;

            }

			
		
	
		}
        public double MoneyStartPortfolio
        {
            get
            {
                return this.moneyStartPortfolio;
            }
            set
            {
                this.moneyStartPortfolio = value;
            }
        }
		public  double MoneyStart
		{
			get
			{
				return this.moneyStart;
			}
			set
			{
				this.moneyStart = value;
			}
		}
//		public  double QuoteShare
//		{
//			get
//			{
//
//				//Debug.Assert(this.dateIndex >= 0,"Software Error getting quote - index not OK");
//				if(this.dateIndex >= 0)
//                    return GetQuoteForIndex(this.dateIndex );
//				else
//					return -100F;
////				if(this.dateIndex >= this.dataItem.DataClass.QuoteCollection.Count)
////				{
////					System.Diagnostics.Debug.Assert(false,"False date index with share " + this.dataItem.DataClass.Name);
////					this.dateIndex = this.dataItem.DataClass.QuoteCollection.Count;
////				}
////				if(this.dateIndex < 0)
////					return 0F;
////				else
////					return this.dataItem.DataClass.QuoteCollection[this.dateIndex].CLOSEc;
//			}
//		}

		//for disply in the grid
		public  double QuoteShare
		{
			get
			{
				if(this.portfolio != null)
					return this.ValueTotal;
				else
				{
					if(this.dateIndex >= 0)
						return GetQuoteForIndex(this.dateIndex );
					else
						return -100F;
				}

			
			}
		}
		protected double GetQuoteForIndex(int ind)
		{
			IListQuotes qColl = this.dataItem.DataClass.QuoteCollection;
			if(ind >= qColl.Count)
			{
				System.Diagnostics.Debug.Assert(false,"False date index with share " + this.dataItem.DataClass.Name);
				ind = qColl.Count;
			}
			if(ind < 0)
				return 0F;
			else
				return qColl[ind].CLOSEc;
		}
		public  double QuoteLastDay
		{
			get
			{
				return GetQuoteForIndex(this.dateIndex -1);
				//int dateInd;	
			}
		}
		public  double QuoteShareLastTrade
		{
			get
			{
				return this.quoteShareLastTrade;
			}
			set
			{
				this.quoteShareLastTrade = value;
				this.quoteShareMaxSinceLastTrade = value;
				this.quoteShareMinSinceLastTrade = value;


			}
		}
		public  double QuoteShareMinSinceLastTrade
		{
			get
			{
				return this.quoteShareMinSinceLastTrade;
			}
			set
			{
				this.quoteShareMinSinceLastTrade = value;
			}
		}
		public  double QuoteShareMaxSinceLastTrade
		{
			get
			{
				return this.quoteShareMaxSinceLastTrade;
			}
			set
			{
				this.quoteShareMaxSinceLastTrade = value;
			}
		}
		
		public   CUtil.TradeType TradeType
		{
			get
			{
				return this.tradeType;
			}
			set
			{
				this.tradeType = value;
			}
		}
		
		//for displaying in the grid
		public   string TradeTypeDisplay
		{
			get
			{
				if(this.tradeType == CUtil.TradeType.Nothing)
					return "--";
				else
                    return this.tradeType.ToString();
			}
		
		}
        //for displaying in the grid
        public bool TradeSimulationInitiaded
		{
			get
			{
				return tradeSimulationInitiaded;
				
			}
            set
            {
                tradeSimulationInitiaded = value;
            }
		
		}
		

		public  CUtil.TradeType TradeTypeMoneyPossible
		{
			get
			{
				return this.tradeTypePossible;
			}
			set
			{
				this.tradeTypePossible = value;
			}
		}
		public  IIndicators IndicatorsSell
		{
			get
			{
				return this.indicatorsSell;
			}
			set
			{
				this.indicatorsSell = value;
			}
		}
		public  IIndicators IndicatorsBuy
		{
			get
			{
				return this.indicatorsBuy;
			}
			set
			{
				this.indicatorsBuy = value;
			}
		}
		public TradeWriteModes TradeWriteMode
		{
			get
			{
				return this.tradeWriteMode;
			}
			set
			{
				this.tradeWriteMode = value;
			}
		}
        public ITradeSystem TradeSystem
		{
			get
			{
                return this.tradeSystem;
			}
			set
			{
                this.tradeSystem = value;
			}
		}
        
		public string NameItem
		{
			get
			{
				if(this.dataItem != null)
					return this.dataItem.DataClass.Name;
				else
					return this.portfolio.Name;
			}
		
		}
	

		public double MaxMoneyForBuyPerPortfolio
		{
			get
			{
				return this.maxMoneyForBuyPerPortfolio;
			}
			set
			{
				//have to set it for calc. of the Simulation of indiviadual shares
				this.maxMoneyForBuyPerPortfolio = value;
			}
		}
     
		
		public double MaxMoneyForBuyPerShare
		{
			get
			{
				return this.maxMoneyForBuyPerShare;
			}
			set
			{
				this.maxMoneyForBuyPerShare = value;
			}
		}
		public double MinimalTransactionCost
		{
			get
			{
				return this.minimalTransactionCost;
			}
			set
			{
				this.minimalTransactionCost = value;
			}
		}
		public double MaximalTransactionCost
		{
			get
			{
				return this.maximalTransactionCost;
			}
			set
			{
				this.maximalTransactionCost = value;
			}
		}
		
		public double ConstSingleTransactionPercentageCost
		{
			get
			{
				return this.constSingleTransactionPercentageCost;
			}
			set
			{
				this.constSingleTransactionPercentageCost = value;
			}
		}
		public double MinmalTransactionAmount
		{
			get
			{
				return this.minmalTransactionAmount;
			}
			set
			{
				this.minmalTransactionAmount = value;
			}
		}
		//as a percentage of all trades
		public int TradesSuccesfull
		{
			get
			{
                //because a successful trade is tradeSell + tradeBuy
				int noTotal = this.tradeEvents.Count/2 ;
                //int noTotal = this.tradeEvents.Count;
				if(noTotal > 0)
				{
					int noSuccesfull = 0;
					for(int i = 0; i < this.tradeEvents.Count; i++)
					{
						TradeEvent te = this.tradeEvents[i] as TradeEvent;
						if(te.TradeEventType == CUtil.TradeEventType.Win)
						{
							noSuccesfull++;
						}

					}
					double f = noSuccesfull * 100 / noTotal;
                    if (f > 100)
                    {
                        Debug.WriteLine("Check TradesSuccesfull");
                    }
					return Convert.ToInt32(f);
				}
				return 0;

				//return this.succesfullTrades;
			}
			
		}
		public int TradesNumber
		{
			get
			{

				
				int noTotal = this.tradeEvents.Count / 2;
				return noTotal;
				
			}
			
		}
		

		

		#region futures


		public bool FuturesTrade
		{
			get
			{
				return this.futuresTrade;
			}
			set
			{
				this.futuresTrade = value;
			}
		}
		
		public double FuturesMoneyPerTick
		{
			get
			{
				return this.futuresMoneyPerTick;
			}
			set
			{
				this.futuresMoneyPerTick = value;
			}
		}
		public double FuturesContractValue
		{
			get
			{
				return this.futuresContractValue;
			}
			set
			{
				this.futuresContractValue = value;
			}
		}
		public double FuturesBankCost
		{
			get
			{
				return this.futuresBankCost;
			}
			set
			{
				this.futuresBankCost = value;
			}
		}
		
		#endregion

        
        public ITrader Trader
        {
            get
            {
                return this.trader;


            }
            set
            {
                this.trader = value;
            }
        }
	
		//for displaying in the grid
		public string ItemName
		{
			get
			{
				if(this.portfolio != null)
				{
					return this.portfolio.Name;
				}
				else
				{
					return this.dataItem.DataClass.Name;
				}

			}
		
		}
  
        [System.Xml.Serialization.XmlIgnoreAttribute()]
        public ITradeSystem TradeSystemForShortSell
        {
            get
            {
                return this.tradeSystemForShortSell;
            }
            set
            {
                this.tradeSystemForShortSell = value;
            }
        }


        
        public double CalculatePerformance()
        {
            double sum = 0F;
            for (int i = 0; i < tradeEvents.Count; i++)
            {
                TradeEvent te = this.tradeEvents[i] as TradeEvent;
                if (te.ShareID == "MoneyTransfer")
                    sum += te.Money;
            }
            //sum += this.money;
            if (sum != 0F)
                sum = this.portfolio.Value_Total * 100 / sum - 100;

            return sum;

        }
        
        public void CreateListPerYearCollection()
        {

            this.performancePerYearCollection = new NameObjectCollection();
            this.performanceRelativePerYearCollection = new NameObjectCollection();
            this.performanceBuyAndHoldPerYearCollection = new NameObjectCollection();
            
            //1. get the first year + leading collection:
            NameObjectCollection leadingCollection = new NameObjectCollection();
            for (int i = 0; i < this.portfolio.DataItems.Count; i++)
            {
                NameObjectCollection noc = this.portfolio.DataItems[i].TradeStep.PerformancePerYearCollection;
                int firstYear = 5000;

                if (noc != null && noc.Count > 0)
                {
                    string strYear = noc.Keys[0];
                    int year = Convert.ToInt32(strYear);
                    if (year < firstYear)
                    {
                        leadingCollection = noc;
                        firstYear = year;
                    }
                }

            }
            //1.1 make a copy of it for the average

            NameObjectCollection averageColl = new NameObjectCollection();
            NameObjectCollection averageCollNumber = new NameObjectCollection();
            NameObjectCollection averageRelColl = new NameObjectCollection();
            NameObjectCollection averageShareColl = new NameObjectCollection();


            for (int yearIndex = 0; yearIndex < leadingCollection.Count; yearIndex++)
            {

                averageColl[leadingCollection.Keys[yearIndex]] = 0F;
                averageRelColl[leadingCollection.Keys[yearIndex]] = 0F;
                averageShareColl[leadingCollection.Keys[yearIndex]] = 0F;
                averageCollNumber[leadingCollection.Keys[yearIndex]] = 0;
            }

            //3. fill the list share by share
            if (this.portfolio != null)
            {
                for (int i = 0; i < this.portfolio.DataItems.Count; i++)
                {
                    ITradeStep ts = this.portfolio.DataItems[i].TradeStep;
                    //create the collection for the share
                  
                    //4. share name

                    NameObjectCollection noc = ts.PerformancePerYearCollection;
                    NameObjectCollection nocRelative = ts.PerformanceRelativePerYearCollection;
                    NameObjectCollection nocShare = ts.PerformanceBuyAndHoldPerYearCollection;

                    if (noc != null && noc.Count > 0)
                    {
                        for (int yearIndex = 0; yearIndex < leadingCollection.Count; yearIndex++)
                        {
                            string strYear = leadingCollection.Keys[yearIndex];
                            //int yearIndex = Convert.ToInt32(strYear);
                            if (noc[strYear] != null)
                            {
                                

                                averageColl[strYear] = Convert.ToDouble(averageColl[strYear]) + Convert.ToDouble(noc[strYear]);
                                averageRelColl[strYear] = Convert.ToDouble(averageRelColl[strYear]) + Convert.ToDouble(nocRelative[strYear]);
                                averageShareColl[strYear] = Convert.ToDouble(averageShareColl[strYear]) + Convert.ToDouble(nocShare[strYear]);

                                averageCollNumber[strYear] = Convert.ToInt32(averageCollNumber[strYear]) + 1;

                            }
                        }


                    }


                }

            }

            for (int yearIndex = 0; yearIndex < averageColl.Count; yearIndex++)
            {
                string strYear = averageColl.Keys[yearIndex];

                //int yearIndex = Convert.ToInt32(strYear);
                int iYearNumber = Convert.ToInt32(averageCollNumber[strYear]);
                if (averageColl[strYear] != null && iYearNumber != 0)
                {
                    double fVal = Convert.ToDouble(averageColl[strYear]) / iYearNumber;
                    fVal = Convert.ToDouble(System.Math.Round(fVal, 2));
                    averageColl[strYear] = fVal;

                    fVal = Convert.ToDouble(averageRelColl[strYear]) / Convert.ToInt32(averageCollNumber[strYear]);
                    fVal = Convert.ToDouble(System.Math.Round(fVal, 2));
                    averageRelColl[strYear] = fVal;

                    fVal = Convert.ToDouble(averageShareColl[strYear]) / Convert.ToInt32(averageCollNumber[strYear]);
                    fVal = Convert.ToDouble(System.Math.Round(fVal, 2));
                    averageShareColl[strYear] = fVal;

                    if (averageColl[strYear] != null)
                    {
                        this.performancePerYearCollection[strYear] = averageColl[strYear];
                    }
                    if (averageRelColl[strYear] != null)
                    {
                        this.performanceRelativePerYearCollection[strYear] = averageRelColl[strYear];

                    }
                    if (averageShareColl[strYear] != null)
                    {
                        this.performanceBuyAndHoldPerYearCollection[strYear] = averageShareColl[strYear];

                    }



                }
            }


        }

	}
}
